<?php
/*****************************************
 This file is part of the Dynamo Core CMS
 Copyright (c) Dynamo Studios 2008

 *** NOTE ***
 Permission is hereby granted to execute this file as a
 web service under the terms of the license agreement.

 See LICENSE.txt, in the system folder.

 All other rights, other than those expressed in the license
 document, are reserved.

 ****************************************/

/**
 * @name Class Manager
 * @version 0.3.2 (Alvin)
 * @abstract
 * Provides classes for the management of object classes, indexes, and
 * the mapping of indexes to objects as 'core attributes'.
 *
 * @author Sean Micklethwaite
 */


global $gzClass;	// Class object array
global $gzClassId;	// Class ID array
global $gzIndex;
global $gzIndexName;

class cDycmsClass extends cDbClass
{
	protected $mzIndex;

	function __construct($arg = null, $byNum = true,
			$z_cAttrib = null)
	{
		if($byNum)
		{
			$this->miClassNum = $arg;
			$this->Read(true);
		}
		else if($z_cAttrib === null)
		{
			$this->msClassId = $arg;
			$this->Read(false);
		}
		else if(is_array($z_cAttrib))
		{
			//
			// Load/create new from array
			//

			$this->miClassNum = $z_cAttrib['cnum'];
			$this->msClassId = $z_cAttrib['id'];
			$this->msName = $z_cAttrib['name'];
			$this->msIcon = $z_cAttrib['icon'];
			$this->msDescription = $z_cAttrib['description'];
			$this->mzToken[0] = (float)$z_cAttrib['public'];
			$this->mzToken[1] = (float)$z_cAttrib['protected'];
			$this->mzToken[2] = (float)$z_cAttrib['private'];
			$this->mToken = (float)$z_cAttrib['token'];

			return;
		}

		//
		// For loaded classes - load core attributes
		//

		if(is_array($this->mzCoreAttributes))
		{
			foreach ($this->mzCoreAttributes as $id_idx => $val)
			{
			 	$idx = &dyLoadIndex($id_idx);
				$this->mzCoreAttributes[$idx->GetName()] =& $idx;
				unset($this->mzCoreAttributes[$id_idx]);
			}
		}
	}

	function & CreateObject()
	/**
	 * Creates a new instance of the class
	 */
	{
		$s_objCls = 'cls'.$this->msClassId;
		return new ${s_objCls}();
	}

	function & LoadObject($id)
	/**
	 * Loads an existing instance of the class, by ID
	 */
	{
		$s_objCls = 'cls'.$this->msClassId;
		return new ${s_objCls}($id);
	}

    function & LoadObjectByArray($zAttrib)
	/**
	 * Loads an existing instance of the class, by attribute array
	 */
	{
		$s_objCls = 'cls'.$this->msClassId;
		return new ${s_objCls}($zAttrib);
	}

    function GetIndexValue($id_obj, $idx)
	/**
	 * Returns a value corresponding to one of the object's core
     * attributes.
	 *
	 * @param $id_obj - Object ID
	 */
	{
		if(isset($this->mzCoreAttributes[$idx]))
			return $this->mzCoreAttributes[$idx]->GetValue($this->miClassNum, $id_obj);
		else
			return dyLoadIndexByName($idx)->GetValue($this->miClassNum, $id_obj);
	}

	function GetIndexValues($id_obj)
	/**
	 * Returns an array containing values for an object's core
	 * attrubutes, with the key being index ID.
	 *
	 * @param $id_obj - Object ID
	 */
	{
		if(!is_array($this->mzCoreAttributes))
			return null;

		$z_idxVal = Array();

		foreach ($this->mzCoreAttributes as $idxName => $idx)
		{
			$z_idxVal[$idxName] = $idx->GetValue($this->miClassNum, $id_obj);
		}

		return $z_idxVal;
	}

	function GetNewIndexValues()
	/**
	 * Returns an array containing blank values for an object's core
	 * attrubutes, with the key being index ID
	 */
	{
		if(!is_array($this->mzCoreAttributes))
			return null;

		$z_idxVal = Array();

		foreach ($this->mzCoreAttributes as $id_idx => $idx)
		{
			$z_idxVal[$idx->GetName()] = "";
		}

		return $z_idxVal;
	}

	function SetIndexValues($id_obj, $vz_idxVal)
	{
		foreach ($vz_idxVal as $idxName => $idxVal)
			$this->SetIndexValue($id_obj, $idxName, $idxVal);
	}
	
	function SetIndexValue($idObj, $idxName, $idxVal){
		if(isset($this->mzCoreAttributes[$idxName]))
	 		$this->mzCoreAttributes[$idxName]->SetValue($this->miClassNum, $idObj, $idxVal);
		else
			dyLoadIndexByName($idxName)->AddValue($this->miClassNum, $idObj, $idxVal);
	}

    function GetPublicToken(){
        return $this->mzToken[0];
    }
    function GetProtectedToken(){
        return $this->mzToken[1];
    }
    function GetPrivateToken(){
        return $this->mzToken[2];
    }
    function GetTokenType($tok){
        switch($tok){
            case $this->mzToken[0]: return 'public';
            case $this->mzToken[1]: return 'protected';
            case $this->mzToken[2]: return 'private';
            default: return 'custom';
        }
    }
    function GetCreatePriv(){
    	return ($this->mToken & 0xFF);
	}
	function GetPublishPriv(){
		return (($this->mToken >> 8) & 0xFF);
	}
	function GetManagePriv(){
	 	return (($this->mToken >> 16) & 0xFF);
	}
	function GetSpecialPriv(){
	 	return (($this->mToken >> 24) & 0xFF);
	}
	function GetToken(){
		return $this->mToken;
	}
	
	function GetClassId()
	{
		return $this->msClassId;
	}

	function GetClassNum()
	{
		return $this->miClassNum;
	}
    function GetName(){
        return $this->msName;
    }
    function GetIcon(){
        return $this->msIcon;
    }
    function GetDescription(){
     	return $this->msDescription;
    }
}

class cDycmsIndex extends cDbIndex
{
	function __construct($arg, $byId = true, $s_regEx = null)
	{
		if($byId == true)
		{
			//
			// Arg is index ID, read by ID
			//

			$this->miIndexId = $arg;
			$this->Read(true);
		}
		else if(!isset($s_regEx))
		{
			//
			// Read index by name
			//
			
			$this->msName = $arg;
			$this->Read(false);
		}
		else
		{
			//
			// Creating new index - initialize values
			//

			$this->miIndexId = 0;
			$this->msName = $arg;
			$this->miRefCount = 0;
			$this->msRegEx = $s_regEx;
			$this->mbModified = true;
		}
	}

	function GetValue($id_clsNum, $id_obj)
	{
		return $this->ReadValue($id_clsNum, $id_obj);
	}

	function SetValue($id_clsNum, $id_obj, $s_val)
	{
		if($id_obj <= 0)
			throw new dyExValidation("Trying to publish non-existent object");
		
		return $this->WriteValue($id_clsNum, $id_obj, $s_val);
	}
	
	function AddValue($id_clsNum, $id_obj, $s_val)
	{
		if($id_obj <= 0)
			throw new dyExValidation("Trying to publish non-existent object");
		
		return $this->WriteValue($id_clsNum, $id_obj, $s_val, true);
	}

	function GetName(){
		return $this->msName;
	}
	function GetId(){
		return $this->miIndexId;
	}
}

function & dyLoadClass($id_clsNum)
{
	global $gzClass, $gzClassId;

	if(!isset($gzClass[$id_clsNum]))
	{
		dyLog("Loading class #".$id_clsNum);

		$gzClass[$id_clsNum] = new cDycmsClass($id_clsNum, true);
		$gzClassId[$gzClass[$id_clsNum]->GetClassId()] = $gzClass[$id_clsNum];
	};

	//
	// Include class file
	//

	require_once(ROOT."class/".$gzClass[$id_clsNum]->GetClassId().".php");
	return $gzClass[$id_clsNum];
}

function & dyLoadClassById($s_cls)
{
	global $gzClass, $gzClassId;

	if(!isset($gzClassId[$s_cls]))
	{
		//
		// Class not loaded - load it
		//

		dyLog("Loading class ".$s_cls);

		$gzClassId[$s_cls] = new cDycmsClass($s_cls, false);
		$gzClass[$gzClassId[$s_cls]->GetClassNum()] = &$gzClassId[$s_cls];
		require_once(ROOT."class/$s_cls.php");
	};

	return $gzClassId[$s_cls];
}

function & dyLoadIndex($id_idx)
{
	global $gzIndex, $gzIndexName;

	if(!isset($gzIndexName[$idx]))
	{
		//
		// Load the index
		//

		dyLog("Loading index #".$id_idx);

		$gzIndex[$id_idx] = new cDycmsIndex($id_idx);
		$gzIndexName[$gzIndex[$id_idx]->GetName()] &= $gzIndex[$id_idx];
	}

	return $gzIndex[$id_idx];
}

function & dyLoadIndexByName($idx)
{
	global $gzIndexName,$gzIndex;

	if(!isset($gzIndexName[$idx]))
	{
		//
		// Load the index
		//

		dyLog("Loading index: ".$idx);

		$gzIndexName[$idx] = new cDycmsIndex($idx, false);
		$gzIndex[$gzIndexName[$idx]->GetId()] &= $gzIndexName[$idx];
	}

	return $gzIndexName[$idx];
}

function dyCreateObject($clsid, $tokentype = NULL)
{
    dyLog("OS: Creating object, clsid:$clsid");

	$class = &dyLoadClassById($clsid);
	$obj = $class->CreateObject();

    dyLog("Object created");
    return $obj;
}

function dyLoadObject($clsid, $id = NULL)
{
	dyLog("OS: Loading object(s), clsid:$clsid");

	$class = &dyLoadClassById($clsid);

	if($id !== null)
	{
		$obj = $class->LoadObject($id);
	}
	else
	{
		// Load all objects in class
		$obj = new cDycmsObjectQuery($clsid);
		$obj->Execute();
	}

	dyLog("OS: Object loaded");
	return $obj;
}

function dyLoadObjectByArray($zAttrib)
{
	$class = &dyLoadClassById($zAttrib['$clsid']);
	return $class->LoadObjectByArray($zAttrib);
}
?>
